/*
 * meter_com.cpp
 *
 *  Created on: 2019-7-30
 *      Author: root
 */

#include "meter_com.h"
#include "program.h"
#include "log_main.h"

#ifdef NW_CLIENT
#include "meter_nw.h"
#include "pro_104.h"
#endif

#ifdef XJ_MQTT_CLIENT
#include "meter_xj.h"
#endif

#ifdef ORDERLY_CHARGE
#include "Interface_dllfk.h"
#endif

#ifdef QL_CLOUD_CLIENT
#include "meter_ql.h"
#endif

#include "app_debug_main.h"


Meter_Info meter_info_tab[]={{1,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},//
		{2,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},2,1000},
		{2,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},
		{3,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},
		{4,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},
		{5,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},
		{6,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},
		{7,{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},1,1000},

};

// 电表实时数据 
MeterDataReal g_realData[GUN_NUM+1];
// 电表故障 
u8 meter_err_state[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// 遥测数据（CAN）
union u_out_mx ycdata_main[GUN_NUM];

// 1: 电流故障，0:正常，2: 电压故障，3: 
int checkMtDataErr(u8 gunid,u8 flag)
{
	int dt;
	static u8 pos_first[GUN_NUM];
	static u8 num[GUN_NUM];
	static u32 pw[GUN_NUM][READ_NUM];
	static TDateTime tm[GUN_NUM][READ_NUM];
	static u32 kWh[GUN_NUM][READ_NUM];
	static u8 err_num[GUN_NUM][READ_NUM];
	static int real_i[]={0,0,0,0,0,0,0,0};
	u32 dt_tm=0;
	int i;
	TDateTime curtm;
	read_current_datetime(&curtm);

    // 通讯计量故障，清除之前的统计数据 
    printf("检测计量故障！！！！！！！flag=%d \n",flag);//401
	if(flag==1)
	{

		printf("检测计量故障！！！！！！！flag=%d \n",flag);
		for(i=0;i<READ_NUM;i++)
		{
		   pw[gunid][i]=0;
		   kWh[gunid][i]=0;
		   err_num[gunid][i]=0;
		   tm[gunid][i]=curtm;
		}
		   pos_first[gunid]=0;
		   real_i[gunid]=0;
//		   num_err[gunid][1]=0;
//		   num_err[gunid][2]=0;
		   num[gunid]=0;
		   return 0;
	}

    int yc_I=ycdata_main[gunid].dc.MX[1];       // BMS系统充电电流 
    int real_I=(g_realData[gunid].current[0]+50)/100;   // 电表电流 
    u32 pw_cur=0,pw_pj=0,kwh1=0,kwh2=0;
	if (yc_I < 0)
		yc_I = -yc_I;
	if (real_I < 0)
		real_I = -real_I;
 // 	sprintf(_tmp_print_str," 进入检测计量程序！！！！！！！  gunid=%d  real_I=%d   yc_I=%d  数据项标志=%x\n ", gunid,(int)g_realData[gunid].current[0],yc_I,g_realData[gunid].read_flag);
 // 	fs_debug_104(_tmp_print_str);
    if(ycdata_main[gunid].dc.MX[2]<=1)      // SOC 
    {
    	printf("遥测数据soc ycdata_main[gunid].dc.MX[2]=%d gunid=%d\n",ycdata_main[gunid].dc.MX[2],gunid);
    	return -1;
    }
    if(g_realData[gunid].read_flag!=0x0f)
    {
    	printf("未能抄到全部数据项 g_realData[gunid].read_flag=%x",g_realData[gunid].read_flag);

    	return -2;
    }


    //电流检测
	if (yc_I > 300) {
		dt = yc_I - real_I;
		if (dt < 0)
			dt = -dt;
		dt *= 100;
		dt = dt / yc_I;
		if (dt > 20) {

			printf("111遥测电流=%d  抄表电流=%d  %d \n", (int) yc_I, (int) real_I,
					(int) g_realData[gunid].current[0]);

			sprintf(_tmp_print_str, " 检测计量故障结果：gunid=%d  遥测电流=%d  抄表电流=%d  %d err_num[gunid][0]=%d\n",gunid,
					(int) yc_I, (int) real_I,
					(int) g_realData[gunid].current[0],
					 err_num[gunid][0]);
			fs_debug_104(_tmp_print_str);
			err_num[gunid][0]++;
			if(err_num[gunid][0]>5)
				return 1;
			else
				return 0;

		}
		else
		{
			err_num[gunid][0]=0;
			dt=real_I-real_i[gunid];
			if(dt<0)
				dt=-dt;
			if(dt>30)
				return -3;

		}
	} else {
//		sprintf(_tmp_print_str, " 检测计量数据，本次遥测电流<30A：不测试！ gunid=%d  \n ", gunid);
//		fs_debug_104(_tmp_print_str);
		return -3;
	}

	//检测电压
	if (ycdata_main[gunid].dc.MX[0] != 0) {
		dt = (u32) ycdata_main[gunid].dc.MX[0] - g_realData[gunid].voltage[0];
		if (dt < 0)
			dt = -dt;
		dt *= 100;
		dt = dt / ycdata_main[gunid].dc.MX[0];
		if (dt > 20) {
			printf("遥测电压=%d  抄表电压=%d   \n", (int) ycdata_main[gunid].dc.MX[0],
					(int) g_realData[gunid].voltage[0]);
//			sprintf(_tmp_print_str, " 检测计量故障结果：遥测电压=%d  抄表电压=%d   \n",
//					(int) ycdata_main[gunid].dc.MX[0],
//					(int) g_realData[gunid].voltage[0]);
//			fs_debug_104(_tmp_print_str);
			err_num[gunid][1]++;
			if(err_num[gunid][1]>5)
				return 2;
			else
				return 0;

		}
		else
			err_num[gunid][0]=0;
	}

	else {
		sprintf(_tmp_print_str, " 检测计量故障出现遥测电压为0：不正常！ gunid=%d  \n ", gunid);
		fs_debug_104(_tmp_print_str);
		return -4;
	}


    printf("222遥测电流=%d  抄表电流=%d  %d \n",(int)yc_I,(int)real_I,(int)g_realData[gunid].current[0]);

    //检测功率

	if (g_realData[gunid].Power != 0) {
		pw_cur = g_realData[gunid].voltage[0] * g_realData[gunid].current[0];
		pw_cur = (pw_cur + 500) / 1000;
		dt = pw_cur - g_realData[gunid].Power;
		dt *= 100;
		dt = dt / g_realData[gunid].Power;
		if (dt > 20) {
			printf("111抄表功率=%d  计算功率=%d   \n", (int) g_realData[gunid].Power,
					(int) pw_cur);
//			sprintf(_tmp_print_str, " 检测计量故障结果：抄表功率=%d  计算功率=%d   \n",
//					(int) g_realData[gunid].Power, (int) pw_cur);
//			fs_debug_104(_tmp_print_str);
			err_num[gunid][2]++;
			if(err_num[gunid][2]>5)
				return 3;
			else
				return 0;

		}
	} else {

		sprintf(_tmp_print_str, " 检测计量故障出现功率为0：不正常！ gunid=%d  \n ", gunid);
		fs_debug_104(_tmp_print_str);
		return -5;
	}

	printf("222抄表功率=%d  计算功率=%d   \n",(int)g_realData[gunid].Power,(int)pw_cur);



     if(num[gunid]<READ_NUM)
     {
    	 pw[gunid][num[gunid]]=g_realData[gunid].Power;
    	 kWh[gunid][num[gunid]]=g_realData[gunid].kWh[0];
    	 tm[gunid][num[gunid]]=curtm;
    	 num[gunid]++;
     }
     else
     {
    	 pw[gunid][pos_first[gunid]]=g_realData[gunid].Power;
    	 kWh[gunid][pos_first[gunid]]=g_realData[gunid].kWh[0];
    	 tm[gunid][pos_first[gunid]]=curtm;
    	 pos_first[gunid]++;
    	 if(pos_first[gunid]==READ_NUM)
    		 pos_first[gunid]=0;
     }

     if(num[gunid]<READ_NUM)
     {
//    	  	sprintf(_tmp_print_str," 检测计量故障结果：正常！！！！！！！！！！！！！ gunid=%d num[gunid]=%d \n ", gunid,num[gunid]);
//    	  	fs_debug_104(_tmp_print_str);

    	 return 0;
     }
     for(i=0;i<num[gunid];i++)
     {
    	 pw_pj+=pw[gunid][i];
     }
     pw_pj/=num[gunid];

     printf("抄表平均功率=%d  计算功率个数=%d   \n",(int)pw_pj,(int)num[gunid]);


     if(num[gunid]<READ_NUM || pos_first[gunid]==0)
     {
    	 dt_tm=diff_DateTime_Sec(&tm[gunid][pos_first[gunid]],&tm[gunid][num[gunid]-1]);
         kwh2=kWh[gunid][num[gunid]-1]-kWh[gunid][pos_first[gunid]];
     }
     else
     {
    	 dt_tm=diff_DateTime_Sec(&tm[gunid][pos_first[gunid]],&tm[gunid][pos_first[gunid]-1]);
         kwh2=kWh[gunid][pos_first[gunid]-1]-kWh[gunid][pos_first[gunid]];
     }

     printf("时间间隔=%d 平均功率=%d  \n ",(int)dt_tm,(int)pw_pj);
     kwh1=(dt_tm*pw_pj)/360000;

//     for(i=0;i<num[gunid];i++)
//     {
//    	 printf("保存在存储中的数据=%d i=%d\n",(int)kWh[gunid][i],i);
//     }
//     printf("num[gunid]-1=%d  pos_first[gunid]=%d kWh[gunid][num[gunid]-1]=%d  kWh[gunid][pos_first[gunid]]=%d\n",num[gunid]-1
//    		 ,pos_first[gunid],(int)kWh[gunid][num[gunid]-1],(int)kWh[gunid][pos_first[gunid]]);

     printf("计算得到两个电量  功率计算得到kwh1=%d   总电量计算得到kwh2=%d  \n ",(int)kwh1,(int)kwh2);
     if( kwh2==0)//pw_pj>200000  &&
     {
		if (pw_pj > 0) {
			printf("注意：电表未走字！！！！！！\n");
			sprintf(_tmp_print_str, "注意：电表未走字！！！！！！pw_pj=%d\n", (int)pw_pj);
			fs_debug_104(_tmp_print_str);
			return 4;
		} else
		{
			sprintf(_tmp_print_str, "注意：电表未走字！！！！！！功率为0");
			fs_debug_104(_tmp_print_str);
			return -6;
		}
     }


 	dt=kwh2-kwh1;
 	if(dt<0)
 		dt=-dt;
 	dt*=100;
 	dt=dt/kwh2;
 	if(dt>30)
 	{
 		printf("检测计量故障结果：故障 功率计算得到kwh1=%d   总电量计算得到kwh2=%d  \n ",(int)kwh1,(int)kwh2);
// 	  	sprintf(_tmp_print_str," 检测计量故障结果：故障 功率计算得到kwh1=%d   总电量计算得到kwh2=%d  \n ",(int)kwh1,(int)kwh2);
// 	  	fs_debug_104(_tmp_print_str);
 		return 5;
 	}

//  	sprintf(_tmp_print_str," 检测计量故障结果：正常！！！！！！！！！！！！！ gunid=%d  \n ", gunid);
//  	fs_debug_104(_tmp_print_str);
 	printf("检测计量故障结果：正常！！！！！！！！！！！！！\n");
	return 0;

}
int HandleMeterErr(u8 meterid,u8 errflag)
{
	static int errnum[]={0,0,0,0,0,0,0,0,0};
	int ret=0;
	if(errflag==0)
	{
		errnum[meterid]=0;
	    meter_err_state[meterid]=0;

	}
	else
	{
	//	   meter_err_state[gunid]=1;
		if(meterid<METER_IN && gm_sys_state[meterid] ==_SYS_START_FIN_)//|| gm_sys_state[gunid] ==_SYS_WAIT_CHARGING_START_
		{
			if(errnum[meterid]<2)
			{
				errnum[meterid]++;
	    	    meter_err_state[meterid]=0;
			}
			else
				meter_err_state[meterid]=1;
				//meter_err_state[meterid]=0;
		}
		else
		{
			meter_err_state[meterid]=1;
			//meter_err_state[meterid]=0;
		}
	}
	//meter_err_state[gunid]=0;
	if(meter_err_state[meterid]==1)
	{
		if(meterid==METER_IN)
			debug_meter("输入电表故障！！！！！！\r\n");
	   debug_meter("处理第%d块表的抄表通信故障 ！！！！！！！！！！！\r\n",meterid);
	   g_realData[meterid].failReadMt=1;
	   if(meterid<METER_IN)
	   {
			printf("\r\n\r\n处理第%d块表的抄表通信故障 err=%d！！！！！！！！！！！\r\n", meterid,errflag);
//#ifdef  XJ_MQTT_CLIENT

	   if(main_updateMtDataReal!=NULL)
	       main_updateMtDataReal(meterid,(void*)&g_realData[meterid]);
#ifdef ORDERLY_CHARGE

		        if(protocol_MAS_updateMeter_real_fun!=NULL)
		        	protocol_MAS_updateMeter_real_fun(meterid,(void*) &g_realData[meterid]);

#endif
	   }

	}
	return ret;
}
void initmeter(void* pConf)
{
	static uart_meter mtu;
	int i;
	pconf *conf=(pconf *)pConf;
	printf("电表初始化 conf->INMT_baud=%d  conf->OUTMT_baud=%d \r\n",(int)conf->INMT_baud,(int)conf->OUTMT_baud);

#ifdef  NW_CLIENT
	initModel();
   	mtu.sendData = HandleMeter;
#endif
#ifdef XJ_MQTT_CLIENT
   	mtu.sendData =HandleMeter_xj;
#endif
#ifdef QL_CLOUD_CLIENT
   	mtu.sendData = HandleMeter_ql;
#endif
    for(i=0;i<GUN_NUM+1;i++)
	   g_realData[i].failReadMt=0;

    mtu.in_baud=conf->INMT_baud;
    mtu.meternum=conf->gunnum;
	printf("111电表初始化 conf->INMT_baud=%d  conf->OUTMT_baud=%d \r\n",(int)conf->INMT_baud,(int)conf->OUTMT_baud);
    mtu.out_baud=conf->OUTMT_baud;
    mtu.portnum=conf->mt_portnum;
    mtu.pmeter_para=&meter_info_tab[0];
    mtu.in_phase_num=conf->INMT_phase_num;
    mtu.devtype=conf->devtype;  //413

    mtu.writelog=fs_debug_104;

   	mtu.sendErr = HandleMeterErr;

   	printf("传到电表库的参数  OUTMT_baud=%d   %d  INMT_baud=%d %d\n",(int)mtu.out_baud,(int)conf->OUTMT_baud,(int)mtu.in_baud,(int)conf->INMT_baud);
    for(i=0;i<mtu.meternum;i++)
    {
    	sprintf(_tmp_print_str,"传到电表库的参数  meter_info_tab[%d].ct=%d \n",i,meter_info_tab[i].ct);
    	fs_debug_104(_tmp_print_str);

    }
    protocol_meter_init((void*) &mtu);


}

//void initmeter(void* pConf)
//{
//	static uart_meter mtu;
//	int i;
//	//电表初始化
//	pconf *conf=(pconf *)pConf;
//    for(i=0;i<9;i++)
//	   g_realData[i].failReadMt=0;
//
//
//
//	mtu.baud=conf->FMt_baud;
//	mtu.comno=conf->FMt_comno;
//	mtu.phase_num=conf->phase_num;
//	mtu.meternum=1;
//
//	mtu.sendData=HandleMeter;
//	mtu.sendErr=HandleMeterErr;
//	if(conf->gunnum == 2 && conf->mt_portnum==1)
//	{
//		int i;
//
//		       char temp[7];
//		       strBcd2BcdArray(conf->FMt_Addr,temp);
//		       for(i=0;i<6;i++)
//		       {
//		    	   mtu.addr[0][i]=temp[5-i];
//		       }
//		   //   memcpy(&mtu.addr[0][0],temp,6);
//		       strBcd2BcdArray(conf->SMt_Addr,temp);
//		       for(i=0;i<6;i++)
//		       {
//		    	   mtu.addr[1][i]=temp[5-i];
//		       }
//		 //      memcpy(&mtu.addr[1][0],temp,6);
//		     	mtu.meternum=2;
//
//	}
//	protocol_meter_init((void*) &mtu);
//
//	if (conf->gunnum == 2 && conf->mt_portnum == 2) {
//		static uart_meter mtu1;
//		mtu1.baud = conf->FMt_baud;
//		mtu1.comno = conf->SMt_comno;
//		mtu1.phase_num = conf->phase_num;
//		mtu1.meternum = 1;
//		mtu1.sendData = HandleMeter;
//		mtu1.sendErr = HandleMeterErr;
//
//		protocol_meter_init((void*) &mtu1);
//	}
//
//
//}
